package com.crazyhat.crazyhat.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import com.crazyhat.crazyhat.entity.Club;
import com.crazyhat.crazyhat.entity.Footprint;
import com.crazyhat.crazyhat.mapper.ClubMapper;
import com.crazyhat.crazyhat.mapper.FootprintMapper;
import com.crazyhat.crazyhat.pojo.Result;
import com.crazyhat.crazyhat.utils.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazyhat.crazyhat.attribute.TokenPayloadEnum;
import com.crazyhat.crazyhat.attribute.UserTypeEnum;
import com.crazyhat.crazyhat.dto.UserInfoDTO;
import com.crazyhat.crazyhat.entity.Application;
import com.crazyhat.crazyhat.entity.User;
import com.crazyhat.crazyhat.mapper.UserMapper;
import com.crazyhat.crazyhat.pojo.PersonalCenter;
import com.crazyhat.crazyhat.service.IApplicationService;
import com.crazyhat.crazyhat.service.IFavoriteService;
import com.crazyhat.crazyhat.service.IFootprintService;
import com.crazyhat.crazyhat.service.IManageService;
import com.crazyhat.crazyhat.service.IParticipationService;
import com.crazyhat.crazyhat.service.IUserService;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author crazyhat
 * @since 2024-07-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Value("${my-config.aliyun-OSS-config.imageDirectory}")
    private String imageDirectory;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private FootprintMapper footprintMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private IFavoriteService favoriteService;

    @Autowired
    private IParticipationService participationService;

    @Autowired
    private IManageService manageService;

    @Autowired
    private IFootprintService footprintService;

    @Autowired
    private ClubMapper clubMapper;

    @Autowired
    private IApplicationService applicationService;

    @Override
    public User getUserInfo(String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public User getUserInfoByStudentId(String studentId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id", studentId);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public User registerUser(User user) {
        if (userMapper.findByEmail(user.getEmail()) != null) {
            throw new RuntimeException("该邮箱已存在");
        }

        if (userMapper.selectOne(new QueryWrapper<User>().eq("student_id", user.getStudentId())) != null) {
            throw new RuntimeException("该用户ID已存在");
        }

        user.setPassword(Md5Util.getMD5String(user.getPassword())); // Encrypt the password before saving
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
        return user;
    }

    /**
     * 获取我的用户信息
     */
    @Override
    public User getMyInfo() {

        Map<String, Object> map = ThreadLocalUtil.get();
        Integer studentId = (Integer) map.get(TokenPayloadEnum.StudentId.getValue());

        return userMapper.selectById(studentId);
    }

    @Override
    public String getUserType() {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer studentId = (Integer) map.get(TokenPayloadEnum.StudentId.getValue());
        User user=userMapper.selectById(studentId);
        return user.getUserType().getDescription();
    }


    @Override
    public User authenticateUser(String identifier, String password) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", identifier).or().eq("student_id", identifier);
        User user = userMapper.selectOne(queryWrapper);

        if (user == null) {
            System.out.println("User not found for email or studentId: " + identifier);
            return null;
        }

        boolean isPasswordMatch = Md5Util.getMD5String(password).equals(user.getPassword());

        if (!isPasswordMatch) {
            System.out.println("Password mismatch for user: " + identifier);
            return null;
        }

        return user;
    }

    @Override
    public User getUserByEmail(String email) {
        return userMapper.findByEmail(email);
    }

    @Deprecated
    @Override
    public boolean updateUser(User user) {
        return userMapper.updateById(user) == 1;
    }

    @Override
    public User updateUserInfo(User user) {

        if(user==null){
            return null;
        }

        Map<String, Object> map = ThreadLocalUtil.get();
        Integer studentId = (Integer) map.get(TokenPayloadEnum.StudentId.getValue());
        User oldUser=userMapper.selectById(studentId);

        if (oldUser==null) {
            return null;
        }

        if (user.getAge()!=null) {
            if(user.getAge()<=0||user.getAge()>=500){
                return null;
            }else {
                oldUser.setAge(user.getAge());
            }
        }

        if (user.getName()!=null) {
            oldUser.setName(user.getName());
        }

        if (user.getGender()!=null) {
            oldUser.setGender(user.getGender());
        }

        userMapper.updateById(oldUser);
        return oldUser;
    }

    //用户管理 返回用户信息
    @Override
    public List<UserInfoDTO> getAllUsers() {
        List<User> users = userMapper.selectList(new QueryWrapper<>());
        return users.stream().map(user -> {
            UserInfoDTO dto = new UserInfoDTO();
            dto.setName(user.getName());
            dto.setStudentId(user.getStudentId());
            dto.setGender(user.getGender());
            dto.setAge(user.getAge());
            dto.setEmail(user.getEmail());
            dto.setCreateTime(user.getCreateTime());
            dto.setUserType(user.getUserType());
            dto.setAvatarUrl(user.getAvatarUrl());
            return dto;
        }).collect(Collectors.toList());
    }

    //用户管理 批量删除
    @Transactional
    @Override
    public boolean deleteUsers(List<Integer> studentIds) {
        if (studentIds == null || studentIds.isEmpty()) {
            return false;
        }

        // 查询这些用户的身份信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("student_id", studentIds);
        List<User> users = userMapper.selectList(queryWrapper);

        // 过滤掉系统管理员和社团一把手
        List<Integer> nonAdminNonLeaderIds = new ArrayList<>();
        for (User user : users) {
            if (!UserTypeEnum.administrator.equals(user.getUserType())) {
                List<Club> clubs = clubMapper.selectList(new QueryWrapper<Club>().eq("leader_id", user.getStudentId()));
                if (clubs.isEmpty()) {
                    nonAdminNonLeaderIds.add(user.getStudentId());
                } else {
                    throw new RuntimeException("请先转移职位再删除用户: " + user.getStudentId());
                }
            }
        }

        // 如果没有可删除的用户，直接返回 false
        if (nonAdminNonLeaderIds.isEmpty()) {
            return false;
        }

        for (Integer studentId : nonAdminNonLeaderIds) {
            List<Club> clubs = clubMapper.selectList(null);
            for (Club club : clubs) {
                try {
                    String secondManagerJson = club.getSecondManager();
                    if (secondManagerJson != null && !secondManagerJson.isEmpty()) {
                        List<Integer> secondManagers = objectMapper.readValue(secondManagerJson, new TypeReference<List<Integer>>() {});
                        if (secondManagers.remove(studentId)) {
                            club.setSecondManager(objectMapper.writeValueAsString(secondManagers));
                            clubMapper.updateById(club);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException("更新二把手列表时出错: " + e.getMessage());
                }
            }
        }

        // 删除用户足迹
        QueryWrapper<Footprint> footprintQueryWrapper = new QueryWrapper<>();
        footprintQueryWrapper.in("user_id", nonAdminNonLeaderIds);
        footprintMapper.delete(footprintQueryWrapper);

        // 删除用户并将其token加入黑名单
        for (User user : users) {
            if (nonAdminNonLeaderIds.contains(user.getStudentId())) {
                TokenBlacklistUtil.addToBlacklist(user.getEmail(), LocalDateTime.now().plusHours(6));
            }
        }

        int deleted = userMapper.deleteBatchIds(nonAdminNonLeaderIds);
        return deleted == nonAdminNonLeaderIds.size();
    }



    //用户管理 重置用户密码为学号后六位
    @Override
    public boolean resetPassword(Integer studentId) {
        User user = userMapper.selectById(studentId);
        if (user == null) {
            return false;
        }
        String newPassword = String.format("%06d", studentId % 1000000); // 学号后六位
        user.setPassword(Md5Util.getMD5String(newPassword)); // 加密新密码
        return userMapper.updateById(user) == 1;
    }

    /*
    * 获取个人中心信息
    * */
    @Override
    public PersonalCenter getPersonalCenter(int footprintPageNum) {

        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());
        PersonalCenter personalCenter=new PersonalCenter();
        User user=userMapper.selectById(studentId);
        personalCenter.setUser(user);

        personalCenter.setFootprint(footprintService.getPersonalFootprint(footprintPageNum,10));
        return personalCenter;
    }

    /*
    * 用户换头像
    * */
    @Override
    public String changeAvatar(MultipartFile avatar) {
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());

        String originalFileName=avatar.getOriginalFilename();
        if (originalFileName==null) {
            return null;
        }
        String savedfileName = imageDirectory+ UUID.randomUUID().toString()
                + originalFileName.substring(originalFileName.lastIndexOf("."));

        try{
            String result= ObsUtil.uploadFile(savedfileName, avatar.getInputStream());
            User user=userMapper.selectById(studentId);

            // // 删除旧头像
            // String oldUrl = user.getAvatarUrl();
            // if (oldUrl != null && !(oldUrl.isEmpty())) {
            //     ObsUtil.deleteFile(oldUrl);
            // }

            user.setAvatarUrl(result);
            userMapper.updateById(user);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public User adminModifyUserInfo(MultipartFile avatar, String name,String studentId) {
        User user=userMapper.selectById(studentId);
        if(user==null){
            return null;
        }
        if (avatar!=null) {
            String originalFileName=avatar.getOriginalFilename();
            if(originalFileName==null){
                return null;
            }

            String savedfileName = imageDirectory+ UUID.randomUUID().toString()
                    + originalFileName.substring(originalFileName.lastIndexOf("."));

            try{
                String result= ObsUtil.uploadFile(savedfileName, avatar.getInputStream());

                user.setName(name);
                user.setAvatarUrl(result);
                userMapper.updateById(user);
                return user;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        user=userMapper.selectById(studentId);
        user.setName(name);
        userMapper.updateById(user);
        return user;
    }

    @Override
    public User selectById(Integer studentId) {
        return userMapper.selectById(studentId);
    }

    /*
     * 查看我的全部申请
     * */
    @Override
    public Page<Application> personalApplications(int pageNum,int pageSize) {
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());
        QueryWrapper<Application> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("student_id",studentId)
                .orderByDesc("apply_time");
        Page<Application> page = new Page<>(pageNum, pageSize);
        return applicationService.selectPage(page, queryWrapper);
    }

    //用户注销
    @Transactional
    @Override
    public boolean logoutUser(Integer studentId, String email, String token) {
        try {
            // 删除用户
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_id", studentId);
            userMapper.delete(queryWrapper);

            // 将 token 加入黑名单
            TokenBlacklistUtil.addToBlacklist(token, LocalDateTime.now().plusHours(6));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /*
     * 查看我的待审核申请
     * */
    @Override
    public Page<Application> pendingApplications(int pageNum, int pageSize) {
        Map<String,Object> map=ThreadLocalUtil.get();
        Integer studentId=(Integer)map.get(TokenPayloadEnum.StudentId.getValue());
        QueryWrapper<Application> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("student_id",studentId)
                .eq("approval_status","审核中");
        Page<Application> page = new Page<>(pageNum, pageSize);
        return applicationService.selectPage(page, queryWrapper);
    }

}
